package com.myrslok.set;

import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.*;

public class CopyEditFileAction implements ResourceSet.ResourceAction<FileToFileResource> {

    private final List<EditAction> actions = new ArrayList<EditAction>();

    public CopyEditFileAction() {
    }

    /**
     * Convenience constructor for replacing <code>@token@</code> with <code>value</code>.
     * @param token the token to replace.
     * @param value the value to replace token with
     */
    public CopyEditFileAction(@NotNull final String token, @NotNull final String value) {
        addAction(new ReplaceToken(token, value));
    }

    public CopyEditFileAction(@NotNull final EditAction... action) {
        addAction(action);
    }

    public CopyEditFileAction addAction(@NotNull final EditAction... action) {
        actions.addAll(Arrays.asList(action));
        return this;
    }

    @Override
    public void run(@NotNull final FileToFileResource r) {
        try {
            String content = FileUtils.readFileToString(r.getSource());
            for (final EditAction action : actions) {
                content = action.apply(content);
            }
            FileUtils.writeStringToFile(r.getTarget(), content);
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public interface EditAction {
        public String apply(String content);
    }

    public static class ReplaceToken implements EditAction {

        private Map<String, String> tokens;
        private String prefixToken = "@";
        private String sufixToken = "@";

        public ReplaceToken() {
            this(new HashMap<String, String>());
        }

        public ReplaceToken(@NotNull final Map<String, String> tokens) {
            this.tokens = tokens;
        }

        public ReplaceToken(@NotNull final String token, @NotNull final String value) {
            this(new HashMap<String, String>());
            addToken(token, value);
        }

        public ReplaceToken addToken(@NotNull final String token, @NotNull final String value) {
            tokens.put(token, value);
            return this;
        }

        @Override
        public String apply(@NotNull String content) {
            for (final Map.Entry<String, String> token : tokens.entrySet()) {
                //noinspection StringContatenationInLoop
                content = content.replace(prefixToken + token.getKey() + sufixToken, token.getValue());
            }
            return content;
        }
    }

}
